﻿using System;
using System.Collections.Generic;
using UnityEngine;

namespace TC
{
    public class FlowGraphExport : ITranslate<FlowGraph, editor.cfg.blueprint.Blueprint>
    {
        public static Dictionary<Type, TranslateBlueprint> translate = new Dictionary<Type, TranslateBlueprint>()
        {
            //GetVariable
            {typeof(GetBool), new GetBool_blueprint() },
            {typeof(GetInt), new GetInt_blueprint() },
            {typeof(GetObject<int[]>), new GetIntArray_blueprint() },

            {typeof(And), new And_blueprint() },
            {typeof(IntAdd), new IntAdd_blueprint() },
            {typeof(IntSubtract), new IntSubtract_blueprint() },
            {typeof(CompareInt), new CompareInt_blueprint() },
            {typeof(GetPosition), new GetPosition_blueprint() },

            //Action
            {typeof(SetObject<int>), new SetInt_blueprint() },
            {typeof(SetObject<float>), new SetFloat_blueprint() },
            {typeof(SetObject<long>), new SetLong_blueprint() },
            {typeof(SetObject<string>), new SetString_blueprint() },
            {typeof(SetObject<bool>), new SetBool_blueprint() },
            {typeof(SetObject<Vector3>), new SetVector3_blueprint() },
            {typeof(SetObject<GameObject>), new SetGameObject_blueprint() },
            {typeof(SetObject<FlowGraph>), new SetBlueprint_blueprint() },

            {typeof(MoveTo), new MoveTo_blueprint() },
            {typeof(Delay), new Delay_blueprint() },

            {typeof(Entry), new Entry_blueprint() },
            {typeof(Result), new Result_blueprint() },
            {typeof(CallFunc), new CallFunc_blueprint() },
            {typeof(Print), new Print_blueprint() },
            {typeof(IfElse), new IfElse_blueprint() },
            {typeof(SwitchInt), new SwitchInt_blueprint() },

            {typeof(Foreach<>), new Foreach_blueprint() },
        };

        public editor.cfg.blueprint.Blueprint OnTranslate(FlowGraph t)
        {
            editor.cfg.blueprint.Blueprint blue = new editor.cfg.blueprint.Blueprint();
            blue.name = t.name;
            foreach (var nd in t.nodes)
            {
                if (translate.TryGetValue(nd.GetType(), out var tla))
                {
                    tla = translate[nd.GetType()];
                    blue.nodes.Add(tla.OnTranslate(nd));
                }
                else
                {
                    Debug.Assert(false, "dont support export node type : " + nd.GetType().FullName);
                }
            }

            List<ValueWrap> vars = BluePrintEditor.graph.vars;
            foreach (var item in vars)
            {
                if(item.type == VarType.Int)
                {
                    var i = new editor.cfg.blueprint.IntVar();
                    i.defaultValue = (int)item.value;
                    blue.variables.Add(item.name, i);
                }
                else if (item.type == VarType.Float)
                {
                    var i = new editor.cfg.blueprint.FloatVar();
                    i.defaultValue = (float)item.value;
                    blue.variables.Add(item.name, i);
                }
                else if (item.type == VarType.Long)
                {
                    var i = new editor.cfg.blueprint.LongVar();
                    i.defaultValue = (long)item.value;
                    blue.variables.Add(item.name, i);
                }
                else if (item.type == VarType.Bool)
                {
                    var i = new editor.cfg.blueprint.BoolVar();
                    i.defaultValue = (bool)item.value;
                    blue.variables.Add(item.name, i);
                }
                else if (item.type == VarType.String)
                {
                    var i = new editor.cfg.blueprint.StringVar();
                    i.defaultValue = item.ToString();
                    blue.variables.Add(item.name, i);
                }
                else if (item.type == VarType.GameObject)
                {
                    blue.variables.Add(item.name, new editor.cfg.blueprint.GameObjectVar());
                }
                else if (item.type == VarType.Blurprint)
                {
                    blue.variables.Add(item.name, new editor.cfg.blueprint.BlueprintVar());
                }
                else if (item.type == VarType.IntArray)
                {
                    var i = new editor.cfg.blueprint.IntArray();
                    int[] array = item.value as int[];
                    foreach (var tmp in array)
                    {
                        i.defaultValue.Add(tmp);
                    }
                    blue.variables.Add(item.name, i);
                }
                else if (item.type == VarType.FloatArray)
                {
                    var i = new editor.cfg.blueprint.FloatArray();
                    float[] array = item.value as float[];
                    foreach (var tmp in array)
                    {
                        i.defaultValue.Add(tmp);
                    }
                    blue.variables.Add(item.name, i);
                }
                else if(item.type == VarType.LongArray)
                {
                    var i = new editor.cfg.blueprint.LongArray();
                    long[] array = item.value as long[];
                    foreach (var tmp in array)
                    {
                        i.defaultValue.Add(tmp);
                    }
                    blue.variables.Add(item.name, i);
                }
                else if(item.type == VarType.StringArray)
                {
                    var i = new editor.cfg.blueprint.StringArray();
                    string[] array = item.value as string[];
                    foreach (var tmp in array)
                    {
                        i.defaultValue.Add(tmp);
                    }
                    blue.variables.Add(item.name, i);
                }
                else if(item.type == VarType.BoolArray)
                {
                    var i = new editor.cfg.blueprint.BoolArray();
                    bool[] array = item.value as bool[];
                    foreach (var tmp in array)
                    {
                        i.defaultValue.Add(tmp);
                    }
                    blue.variables.Add(item.name, i);
                }
                else if(item.type == VarType.Vector3Array)
                {
                    var i = new editor.cfg.blueprint.Vector3Array();
                    Vector3[] array = item.value as Vector3[];
                    editor.cfg.map.Vector3 v3;
                    foreach (var tmp in array)
                    {
                        v3 = new editor.cfg.map.Vector3();
                        v3.x = tmp.x;
                        v3.y = tmp.y;
                        v3.z = tmp.z;
                        i.defaultValue.Add(v3);
                    }
                    blue.variables.Add(item.name, i);
                }
                else if(item.type == VarType.GameObjectArray)
                {
                    blue.variables.Add(item.name, new editor.cfg.blueprint.GameObjectArray());
                }
                else
                {
                    Debug.Assert(false, "dont support type : " + item.value.GetType().FullName);
                }
            }

            return blue;
        }
    }
}
